﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Web.Hosting;
using System.Web.Http;
using CacheManager.Core;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Unity.WebApi;

namespace KL.UFrame.Core.Unity
{
    public class UnityBootstrapper:IServiceLocator
    {
        private static IUnityContainer _container;


        #region Singleton
       
        private static UnityBootstrapper _current;

        /// <summary>
        /// Call RegisterComponents() first
        /// </summary>
        public static UnityBootstrapper Current=> _current ?? (_current = new UnityBootstrapper());

        private UnityBootstrapper()
        {
            _container = BuildUnityContainer();
        }

        #endregion

        #region 注册

        public void RegisterComponents()
        {
            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(_container);
        }

        /// <summary>
        /// Builds the unity container.
        /// </summary>
        /// <returns></returns>
        private  IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            #region 静态注册

            #region Log

            var logger = NLog.LogManager.GetCurrentClassLogger();
            container.RegisterInstance(logger);

            #endregion

            #region Caching
            var cacheManager = CacheFactory.Build("applicationCache", settings =>
            {
                //Should be aware to using Web cache cache handle because it not worked in native threads. (Hangfire jobs)
                settings
                    .WithUpdateMode(CacheUpdateMode.Up)
                    .WithSystemRuntimeCacheHandle("memCacheHandle")
                        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromDays(1));
            });
            container.RegisterInstance(cacheManager);
            #endregion

            #endregion

            #region 从配置文件中注册

            var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = HostingEnvironment.MapPath("~/Unity.config") };
            System.Configuration.Configuration configuration =
                ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");

            container.LoadConfiguration(unitySection,"default");

            #endregion

            return container;
        }
        #endregion

        #region IServiceLocator Members

        public object GetService(Type serviceType)
        {
            return _container.Resolve(serviceType);
        }

        public TService GetService<TService>()
        {
            return _container.Resolve<TService>();
        }

        public object GetInstance(Type serviceType)
        {
            return _container.Resolve(serviceType); //这个有问题
        }

        public object GetInstance(Type serviceType, string key)
        {
            return _container.Resolve(serviceType, key);
        }

        public IEnumerable<object> GetAllInstances(Type serviceType)
        {
            return _container.ResolveAll(serviceType);
        }

        public TService GetInstance<TService>()
        {
            return _container.Resolve<TService>();
        }

        public TService GetInstance<TService>(string key)
        {
            return _container.Resolve<TService>(key);
        }

        public IEnumerable<TService> GetAllInstances<TService>()
        {
            return _container.ResolveAll<TService>();
        }

        #endregion
    }
}